﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace iMario
{
    public abstract class Sprite2D : GameObject
    {
        //Mục đích của abstract class Sprite2D
        //  - Tập trung các phương thức xử lí của Character, Monster và Shot (đạn) để tiện quản lí và mở rộng
        
        //Danh sách thuộc tính và công dụng
        static public MapManager mapManager;        //Biến đại diện cho MapManager đang được sử dụng trong Game
        static public int Gravity = 4;              //Độ lớn gia tốc trọng trường

        private KindOfSprite _kind;                 //Chứa hình ảnh về sprite tùy theo từng loại sprite được sử dụng
        public KindOfSprite kind
        {
            get { return _kind; }
            set { _kind = value; }
        }

        private int _iTexture;                      //Chỉ số Texture hiện tại của Sprite
        public int iTexture
        {
            get { return _iTexture; }
            set { _iTexture = value; }
        }

        protected Point _graphicLocation;             //Vị trí của Sprite2D trên màn hình game
        public Point graphicLocation
        {
            get { return _graphicLocation; }
            set { _graphicLocation = value; }
        }

        private int _blood;                         //Mức máu hiện tại của sprite
        public int blood
        {
            get { return _blood; }
            set { _blood = value; }
        }

        private bool _isActive;                     //Cờ hiệu cho biết sprite đã được Active chưa
        public bool isActive
        {
            get { return _isActive; }
            set { _isActive = value; }
        }

        private bool _isDead;                       //Cờ hiệu cho biết sprite đã bị chết chưa
        public bool isDead
        {
            get { return _isDead; }
            set { _isDead = value; }
        }

        private int _iUpdate;                       //Chu kì hiện tại của character
        public int iUpdate
        {
            get { return _iUpdate; }
            set { _iUpdate = value; }
        }

        private int _nUpdate;                       //Chu kì lặp để thay đổi frame hình biểu diễn của character, lệ thuộc vào speed của KindOfSprite
        public int nUpdate
        {
            get { return _nUpdate; }
            set { _nUpdate = value; }
        }

        //Danh sách các hàm ảo và công dụng
        //Hàm nhân bản thêm 1 đối tượng thuộc lớp đối tượng mà nó thuộc về và trả về chính đối tượng đã được nhân bản thành công đó
        //  1. Tham số truyền vào: Không có
        //  2. Giá trị trả về:
        //      - Con trỏ GameEntity của đối tượng đã được nhân bản thành công
        public override GameEntity Clone()
        {
            //Không xử lí tại đây vì đây là hàm ảo
            return null;
        }

        //Hàm cập nhật trạng thái của bản đồ
        //  1. Tham số truyền vào:
        //      - KeyboardState _keyboard: Đại diện cho trạng thái của Keyboard
        //      - MouseState _mouse: Đại diện cho trạng thái của Mouse
        //      - GameTime _gameTime: biến đếm thời gian của game
        //  2. Giá trị trả về: Không có
        public override void Update(KeyboardState _keyboard, MouseState _mouse, GameTime _gameTime)
        {
            //Do nothing here
        }
        
        //Hàm xử lí thao tác vẽ
        //  1. Tham số truyền vào:
        //      - SpriteBatch _spriteBatch
        //      - GameTime _gameTime
        //  2. Giá trị trả về: Không có
        public override void Draw(SpriteBatch _spriteBatch, GameTime _gameTime)
        {
            //Thực hiện vẽ đối tượng kind tại client xác định
            //_spriteBatch.Draw(kind.sprite[_iTexture], new Rectangle(graphicLocation.X, graphicLocation.Y, kind.size.X, kind.size.Y), Color.White);
        }

        //Hàm thiết lập giá trị cho MapManager
        //  1. Tham số truyền vào:
        //      - MapManager _inputMapManager
        //  2. Giá trị trả về: Không có
        static public void SetMapManager(MapManager _inputMapManager)
        {
            mapManager = _inputMapManager;
        }

        //Hàm cập nhật tọa độ graphicLocation của đối tượng Sprite2D
        //  1. Tham số truyền vào
        //      - int _x: độ dao động theo phương ngang
        //      - int _y: độ dao động theo phương đứng
        //  2. Giá trị trả về: Không có
        public void AddGraphicLocation(int _x, int _y)
        {
            //Hướng xử lí
            //  1. Cập nhật tọa độ graphicLocation theo _x và _y
            //  2. Kiểm tra nếu giá trị sau khi được thêm vượt quá màn hình và xử lí


            //Tiến hành
            //  1. Cập nhật tọa độ graphicLocation theo _x và _y
            _graphicLocation.X += _x;
            _graphicLocation.Y += _y;

            //  2. Kiểm tra nếu giá trị sau khi được thêm vượt quá màn hình và xử lí
            if (_graphicLocation.Y < 0)
                _graphicLocation.Y = 0;

            if (_graphicLocation.Y + kind.size.Y >= Map.WindowHeigh)
                _graphicLocation.Y = Map.WindowHeigh - kind.size.Y;

            if (_graphicLocation.X < 0)
                _graphicLocation.X = 0;

            if (_graphicLocation.X + kind.size.X >= Map.WindowWidth)
                _graphicLocation.X = Map.WindowWidth - kind.size.X;
        }
    }
} 